#pragma once
#include"Acceptor.hpp"
#include"LoopThread.hpp"
#include"Connection.hpp"

class TcpServer {
    private:
        uint64_t _connection_id;//连接的id,⾃动增⻓(随着连接数量的增长)
        int _port;//端口号
        int _timeout;//超时时间/这是⾮活跃连接的统计时间---多⻓时间⽆通信就是⾮活跃连接
        bool _enable_inactive_connection_close;//是否关闭⾮活跃连接
        Acceptor _acceptor;//监听器
        EventLoop _baseloop;//主事件循环,负责监听新连接
        ThreadPool _Loopthreadpool;//从属EventLoop线程池

        std::unordered_map<uint64_t,ConnPtr> _connections;//连接的集合

        //以下是对新连接设置的回调函数
        ConnectedCallback _conn_cb;//连接成功后的回调函数
        MessageCallback _msg_cb;//接收到消息后的回调函数
        ClosedCallback _closed_cb;//连接关闭后的回调函数
        OtherEventCallback _other_cb;//其他事件回调函数

    private:
        void NewConnection(int newfd)
        {
            ConnPtr conn = std::make_shared<Connection>(_Loopthreadpool.NextLoop(),_connection_id,newfd);
            _connection_id++;
            conn->SetMessageCallback(_msg_cb);
            conn->SetClosedCallback(_closed_cb);
            conn->SetOtherCallback(_other_cb);
            conn->SetConnectedCallback(_conn_cb);
            conn->SetServerClosedCallback(std::bind(&TcpServer::ServerRemoveConnection, this, std::placeholders::_1));
            if(_enable_inactive_connection_close){
                conn->EnableInactiveRelease(_timeout);
            }
            conn->Establish();//就绪一系列操作
            _connections[_connection_id] = conn;//在主线程_baseloop中管理连接信息
        }
        void RemoverConnectionInLoop(const ConnPtr &conn)//这个函数是要压入主线程的任务队列中，原因是避免线程安全问题
        {
            auto it = _connections.find(conn->ConnId());
            if(it!= _connections.end()){
                _connections.erase(it);
            }
        }
        void ServerRemoveConnection(const ConnPtr &conn)//从管理Connection的_conns中移除连接信息
        {
            _baseloop.RuninLoop(std::bind(&TcpServer::RemoverConnectionInLoop, this,conn));
        }
        
        void AddOnTimeTaskInLoop(const Func_Task_Callback &task, uint32_t delay)//Func_Task_Callback是Timewheel内的任务类型
        {
            _baseloop.AddTimeTask(_connection_id,delay,task);
            _connection_id++;
        }

    public:
        TcpServer(int port)
            :_port(port)
            ,_timeout(-1)
            ,_connection_id(0)
            ,_enable_inactive_connection_close(false)
            ,_Loopthreadpool(&_baseloop)//调用线程池的构造函数
            ,_acceptor(&_baseloop, _port)
        {
            _acceptor.SetAcceptCallback(std::bind(&TcpServer::NewConnection, this, std::placeholders::_1));
            _acceptor.Listen();//开启监听,将监听挂在_baseloop上,一旦有新连接到来,会触发读事件,然后调用_acceptor的回调函数,进⾏新连接的创建
        }
        void SetThreadNum(int num)
        {
            _Loopthreadpool.SetThreadNum(num);
        }
        void EnableInactiveConnectionClose(int timeout)
        {
            _timeout = timeout;
            _enable_inactive_connection_close = true;
        }

        void Start()
        {
            _Loopthreadpool.BulidPools();
            _baseloop.Start();
        }
        void AddOnTimeTask(const Func_Task_Callback &task, uint32_t delay)
        {
            _baseloop.RuninLoop(std::bind(&TcpServer::AddOnTimeTaskInLoop, this,task,delay));
        }
        //设置回调函数
        void SetConnectedCallback(const ConnectedCallback& cb) { _conn_cb = cb; }
        void SetMessageCallback(const MessageCallback& cb) { _msg_cb = cb; }
        void SetClosedCallback(const ClosedCallback& cb) { _closed_cb = cb; }
        void SetOtherCallback(const OtherEventCallback& cb) { _other_cb = cb; }

};